package de.tud.binpacking;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import de.tud.binpacking.data.Solution;
import de.tud.binpacking.events.BestSolutionListener;
import de.tud.binpacking.heuristic.construction.AStartHeuristic;
import de.tud.binpacking.heuristic.construction.ForEachOrderOneBatch;
import de.tud.binpacking.instance.Instance;

public class Benchmark implements Runnable {
	
	private Set<BestSolutionListener> solutionFoundListeners = new HashSet<BestSolutionListener>();
	
	private List<Instance> instances = new LinkedList<Instance>();
	private Solution bestSolution = null;
	
	public Benchmark(Collection<Instance> instances) {
		
		if (instances == null) {
			throw new NullPointerException("Instances cannot be null");
		} else if (instances.isEmpty()) {
			throw new IllegalArgumentException("Instances cannot be empty");
		}
		
		this.instances.addAll(instances);
	}
	
	public boolean addSolutionFoundListener(BestSolutionListener listener) {
		return solutionFoundListeners.add(listener);
	}
	
	public void solutionFound(Solution bestSolution) {
		for (BestSolutionListener listener : solutionFoundListeners) {
			try {
				listener.bestSolutionFound(bestSolution);
			} catch(Exception e) {
				solutionFoundListeners.remove(listener);
			}
		}
	}
	
	public Solution getBestSolution() {
		return this.bestSolution;
	}

	@Override
	public void run() {
		
		for (Instance instance : instances) {
			
			AStartHeuristic startHeuristic = new ForEachOrderOneBatch(instance);
			
			new Thread(startHeuristic).start();
			
		} 
	}
}
